package com.csc531.lists;

import java.util.ArrayList;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SimpleCursorAdapter;

import com.csc531.Manager;
import com.csc531.R;
import com.csc531.DataTypes.Course;
import com.csc531.DataTypes.Task;
import com.csc531.adapters.ClassesDbAdapter;
import com.csc531.adapters.ClassesExpandableListAdapter;
import com.csc531.edit.ClassesEdit;

/**
 * @author Javier Figueroa
 * Display a list with expandable wide nodes
 */
public class ClassesFatList extends FatList 
{
	//logging
	private static final String TAG = "CLASSES TAB";

	//menu
	private static final int INSERT_ID = Menu.FIRST;
	private static final int EDIT_ID = Menu.FIRST + 1;
	private static final int DELETE_ID = Menu.FIRST + 2;
	private static final int SWITCH_TO_THINLIST = Menu.FIRST + 3;


	//globals
	private ClassesDbAdapter _mDbHelper;
	private ArrayList<Object> _tasksDatabaseRowIds;
	private ArrayList<Course> _uniqueCourses;

	//----------------------------------------------------------------------------------------------------

	/* (non-Javadoc)
	 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) 
	{
		super.onActivityResult(requestCode, resultCode, intent);
		fillTaskListData();

	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
		super.onCreateOptionsMenu(menu);
		menu.add(0, SWITCH_TO_THINLIST, 0, R.string.menu_switch_to_thinlist);
		menu.add(0, INSERT_ID, 0, R.string.menu_insert);
		menu.add(0, EDIT_ID, 0, R.string.menu_edit);
		menu.add(0, DELETE_ID, 0,  R.string.menu_delete);

		return true;
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
	 */
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) 
	{
		switch(item.getItemId())
		{
		case INSERT_ID:
			createTask();
			return true;
		case EDIT_ID:
			editTask();
			return true;
		case DELETE_ID:
			deleteTask();
			fillTaskListData();
			return true;
		case SWITCH_TO_THINLIST:
			switchToViewAll();
			return true;
		}

		return super.onMenuItemSelected(featureId, item);
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);

		_mDbHelper = new ClassesDbAdapter(this);
		_mDbHelper.open();
		fillTaskListData();
	}


	/**
	 * Fill the tab with a list object containing the tasks
	 */
	private void fillTaskListData() 
	{

		ClassesExpandableListAdapter classesTabAdapter = new ClassesExpandableListAdapter(this);
		_tasksDatabaseRowIds = new ArrayList<Object>();
		_uniqueCourses = new ArrayList<Course>();

		Cursor taskCursor = _mDbHelper.fetchAllTasks();
		startManagingCursor(taskCursor);

		String[] from = new String[]{ClassesDbAdapter.KEY_TITLE};
		int[] to = new int[]{R.id.text1};

		SimpleCursorAdapter simpleTaskCursor = 
			new SimpleCursorAdapter(this, R.layout.notes_row, taskCursor, from, to);

		printTasksToClassesTab(simpleTaskCursor,classesTabAdapter);

		//setListAdapter here
		classesTabAdapter.createGlobalTaskList();

		setListAdapter(classesTabAdapter);
		registerForContextMenu(getExpandableListView());
	}

	/**
	 * Queries the SQLlite to populate the contents of the tab
	 */
	private void printTasksToClassesTab(SimpleCursorAdapter simpleTaskCursor,
			ClassesExpandableListAdapter classesTabAdapter) 
	{
		try 
		{
			simpleTaskCursor.getCursor().moveToFirst();

			int numberOfRows = simpleTaskCursor.getCursor().getCount();
			int numberOfColumns = simpleTaskCursor.getCursor().getColumnCount();

			Log.v(TAG, "num of rows: "+numberOfRows);
			Log.v(TAG, "num of cols: "+numberOfColumns);

			for( int i = 0; i < numberOfRows ; i++ ) 
			{
				addTasksToCourse(simpleTaskCursor);

				simpleTaskCursor.getCursor().moveToNext();
			}

			for(Course course : _uniqueCourses)
			{
				classesTabAdapter.addCourse(course);
			}

			for(Course course: classesTabAdapter.getCourses())
			{
				_tasksDatabaseRowIds.add(course);
				for(Task task: course.getTasks()) 
				{
					_tasksDatabaseRowIds.add(task);	
				}
			}

		} 
		catch(RuntimeException ex) 
		{
			Log.v(TAG,"The List is Empty!!");
		}		
	}

	/**
	 * Traverses the database table and creates Course objects and appends Tasks objects to them
	 */
	private void addTasksToCourse(SimpleCursorAdapter simpleTaskCursor)
	{
		int k = 0;

		String rowId = simpleTaskCursor.getCursor().getString(k++);
		Log.v(TAG, "rowId: "+rowId);

		String courseName = simpleTaskCursor.getCursor().getString(k++);
		Course course = checkTheCourseIsUniqueForDisplay(courseName);

		course.setName(courseName);

		Task task = new Task();
		String title = simpleTaskCursor.getCursor().getString(k++);
		Log.v(TAG, "title: "+title);

		String dueDate = simpleTaskCursor.getCursor().getString(k++);
		task.setDate(dueDate);

		String description = simpleTaskCursor.getCursor().getString(k++);
		task.setDescription(description);

		task.setTitle(
				title +
				" - (" + dueDate + ") - " +
				description
		);

		task.setCourseName(course.getName());
		task.setTaskId(Integer.parseInt(rowId));

		course.addTask(task);
		if(_uniqueCourses.contains(course) == false) 
		{
			_uniqueCourses.add(course);
		}

	}


	/**
	 * Helper method that verifies that a Course being added to the tab content
	 * is not repeated. Called from addTasksToCourse method
	 */
	private Course checkTheCourseIsUniqueForDisplay(String courseName) 
	{
		Course course = new Course();
		for (Course aCourse : _uniqueCourses ) 
		{
			if(aCourse.getName().compareTo(courseName) == 0) 
			{
				course = aCourse;
			}
		}

		return course;
	}

	/**
	 * Action method to switch to the "View All" list type. 
	 */
	private void switchToViewAll() 
	{
		Intent i = new Intent(this, Manager.class);
		i.putExtra("TAB", Manager.CLASSES_TAB);
		i.putExtra("CLASSESVIEWTYPE", Manager.CLASSES_THINLIST);
		startActivity(i);
	}


	/**
	 * Action method to delete a selected task
	 */
	private void deleteTask() 
	{
		if(checkTasksExist() == false)
		{
			return;
		}
		try 
		{
			if(getExpandableListView().getSelectedView().isClickable())
			{
				_mDbHelper.deleteTask(getTaskIdRelatedToDisplay());
			}
		}
		catch(NullPointerException ex)
		{
			Log.v(TAG,ex.toString());
		}
	}

	/**
	 * Action method to edit a selected task
	 */
	private void editTask()
	{
		Intent i = new Intent(this, ClassesEdit.class);

		if(checkTasksExist() == false) 
		{
			return;
		}

		try 
		{
			if(getExpandableListView().getSelectedView().isClickable())
			{

				long id = getTaskIdRelatedToDisplay();

				i.putExtra(ClassesDbAdapter.KEY_ROWID,id);
				startActivityForResult(i, ClassesThinList.ACTIVITY_EDIT);
			}
		}
		catch(NullPointerException ex)
		{
			Log.v(TAG,ex.toString());
		}

	}

	/**
	 * Helper methods that calculates the index of a selected tab 
	 * based on the selectedId from Android's API and the 
	 * _taskDatabaseRowIds ArrayList
	 * 
	 * @return Id of the selected Task
	 */
	private int getTaskIdRelatedToDisplay() 
	{
		Task selectedItem = (Task) getExpandableListView().getSelectedItem();
		int id = (int) getExpandableListView().getSelectedId();
		int relativeDisplayPositionToDatabaseRowIdsList = 0;

		for(int i = 0 ; i < _tasksDatabaseRowIds.size() ; i++ ) 
		{ 
			if(_tasksDatabaseRowIds.get(i) instanceof Course)
			{

				String courseNameSelectedItem = selectedItem.getCourseName();
				String courseNameFromArrayList = ((Course) _tasksDatabaseRowIds.get(i) ).getName();

				if(courseNameSelectedItem.compareTo(courseNameFromArrayList) == 0) {
					relativeDisplayPositionToDatabaseRowIdsList = i + id + 1;
				}

			}
		}
		selectedItem = (Task) _tasksDatabaseRowIds.get(relativeDisplayPositionToDatabaseRowIdsList);

		return selectedItem.getTaskId();
	}

	/**
	 * Action method that creates a new Task
	 */
	private void createTask() 
	{
		Intent i = new Intent(this, ClassesEdit.class);
		startActivityForResult(i, ClassesThinList.ACTIVITY_CREATE);
	}

	/**
	 * Helper method to prevent OutOfBoundsException in the
	 * _tasksDatabaseRowIds ArrayList
	 * 
	 * @return false if the ArrayList is empty
	 */
	private boolean checkTasksExist() 
	{
		if(_tasksDatabaseRowIds.size() <= 0)
		{
			return false;
		}
		else 
		{
			return true;
		}
	}
}
